#pragma once

#include "comm/znx_defs.h"
#include "comm/znx_queue.h"
#include "comm/znx_rbtree.h"
#include "comm/znx_thread_base.h"


typedef struct znx_event_s  znx_event_t;

typedef void(*znx_event_handler_t)(znx_event_t *event);

struct znx_event_s {
    void                    *data;
    znx_event_handler_t     handler;

    znx_rbtree_node_t       timer;
    znx_queue_t             queue;

    // timer task exec time. msecond
    int64_t                 time_key;

    // enabled read event or write event
    unsigned                active:1;
    // write event or read event
    unsigned                write:1;
    // wheter the event is ready
    unsigned                ready:1;
    // current event has eof error.
    unsigned                eof:1;
    // current event has error.
    unsigned                error:1;
    // wheter to add to timer rbtree
    unsigned                timer_set:1;
    unsigned                timer_callback:1;
    // timer expired
    unsigned                timedout:1;
    // for znx_event_loop_post_event.
    unsigned                schedule:1;
    // for graceful shutting down.
    unsigned                cancelable:1;
};

static inline int
znx_event_timer_cmp(znx_rbtree_node_t *a, znx_rbtree_node_t *b) {
    znx_event_t *a_event = znx_rbtree_data(a, znx_event_t, timer);
    znx_event_t *b_event = znx_rbtree_data(b, znx_event_t, timer);

    if (a_event->time_key == b_event->time_key) {
        return 0;
    }

    return a_event->time_key > b_event->time_key ? 1 : -1;
}


typedef struct znx_dispatch_event_s znx_dispatch_event_t;

typedef void(*znx_dispatch_handler_t)(znx_dispatch_event_t *dispatch_event);

struct znx_dispatch_event_s {
    znx_thread_base_t       *setup_thread;
    void                    *data;
    znx_dispatch_handler_t  handler;

    void                    *save_data_1;
    void                    *save_data_2;

    znx_queue_t             queue;

    // for znx_single_flight, identify master task.
    unsigned                is_master:1;
};
